'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var vue = require('vue');
var constants = require('../utils/constants');
var validators = require('../utils/validators');
var util = require('../utils/util');
var form = require('../el-form');

/**
 * Make a map and return a function for checking if a key
 * is in that map.
 * IMPORTANT: all calls of this function must be prefixed with
 * \/\*#\_\_PURE\_\_\*\/
 * So that rollup can tree-shake them if necessary.
 */
const EMPTY_OBJ = (process.env.NODE_ENV !== 'production')
    ? Object.freeze({})
    : {};
const EMPTY_ARR = (process.env.NODE_ENV !== 'production') ? Object.freeze([]) : [];
const objectToString = Object.prototype.toString;
const toTypeString = (value) => objectToString.call(value);

const useCheckboxGroup = () => {
    const ELEMENT = util.useGlobalConfig();
    const elForm = vue.inject(form.elFormKey, {});
    const elFormItem = vue.inject(form.elFormItemKey, {});
    const checkboxGroup = vue.inject('CheckboxGroup', {});
    const isGroup = vue.computed(() => checkboxGroup && (checkboxGroup === null || checkboxGroup === void 0 ? void 0 : checkboxGroup.name) === 'ElCheckboxGroup');
    const elFormItemSize = vue.computed(() => {
        return elFormItem.size;
    });
    return {
        isGroup,
        checkboxGroup,
        elForm,
        ELEMENT,
        elFormItemSize,
        elFormItem,
    };
};
const useModel = (props) => {
    let selfModel = false;
    const { emit } = vue.getCurrentInstance();
    const { isGroup, checkboxGroup } = useCheckboxGroup();
    const isLimitExceeded = vue.ref(false);
    const store = vue.computed(() => { var _a; return checkboxGroup ? (_a = checkboxGroup.modelValue) === null || _a === void 0 ? void 0 : _a.value : props.modelValue; });
    const model = vue.computed({
        get() {
            var _a;
            return isGroup.value
                ? store.value
                : (_a = props.modelValue) !== null && _a !== void 0 ? _a : selfModel;
        },
        set(val) {
            var _a;
            if (isGroup.value && Array.isArray(val)) {
                isLimitExceeded.value = false;
                if (checkboxGroup.min !== undefined && val.length < checkboxGroup.min.value) {
                    isLimitExceeded.value = true;
                }
                if (checkboxGroup.max !== undefined && val.length > checkboxGroup.max.value) {
                    isLimitExceeded.value = true;
                }
                isLimitExceeded.value === false && ((_a = checkboxGroup === null || checkboxGroup === void 0 ? void 0 : checkboxGroup.changeEvent) === null || _a === void 0 ? void 0 : _a.call(checkboxGroup, val));
            }
            else {
                emit(constants.UPDATE_MODEL_EVENT, val);
                selfModel = val;
            }
        },
    });
    return {
        model,
        isLimitExceeded,
    };
};
const useCheckboxStatus = (props, { model }) => {
    const { isGroup, checkboxGroup, elFormItemSize, ELEMENT } = useCheckboxGroup();
    const focus = vue.ref(false);
    const size = vue.computed(() => { var _a; return ((_a = checkboxGroup === null || checkboxGroup === void 0 ? void 0 : checkboxGroup.checkboxGroupSize) === null || _a === void 0 ? void 0 : _a.value) || elFormItemSize.value || ELEMENT.size; });
    const isChecked = vue.computed(() => {
        const value = model.value;
        if (toTypeString(value) === '[object Boolean]') {
            return value;
        }
        else if (Array.isArray(value)) {
            return value.includes(props.label);
        }
        else if (value !== null && value !== undefined) {
            return value === props.trueLabel;
        }
    });
    const checkboxSize = vue.computed(() => {
        var _a;
        const temCheckboxSize = props.size || elFormItemSize.value || ELEMENT.size;
        return isGroup.value
            ? ((_a = checkboxGroup === null || checkboxGroup === void 0 ? void 0 : checkboxGroup.checkboxGroupSize) === null || _a === void 0 ? void 0 : _a.value) || temCheckboxSize
            : temCheckboxSize;
    });
    return {
        isChecked,
        focus,
        size,
        checkboxSize,
    };
};
const useDisabled = (props, { model, isChecked }) => {
    const { elForm, isGroup, checkboxGroup } = useCheckboxGroup();
    const isLimitDisabled = vue.computed(() => {
        var _a, _b;
        const max = (_a = checkboxGroup.max) === null || _a === void 0 ? void 0 : _a.value;
        const min = (_b = checkboxGroup.min) === null || _b === void 0 ? void 0 : _b.value;
        return !!(max || min) && (model.value.length >= max && !isChecked.value) ||
            (model.value.length <= min && isChecked.value);
    });
    const isDisabled = vue.computed(() => {
        var _a;
        const disabled = props.disabled || elForm.disabled;
        return isGroup.value
            ? ((_a = checkboxGroup.disabled) === null || _a === void 0 ? void 0 : _a.value) || disabled || isLimitDisabled.value
            : props.disabled || elForm.disabled;
    });
    return {
        isDisabled,
        isLimitDisabled,
    };
};
const setStoreValue = (props, { model }) => {
    function addToStore() {
        if (Array.isArray(model.value) &&
            !model.value.includes(props.label)) {
            model.value.push(props.label);
        }
        else {
            model.value = props.trueLabel || true;
        }
    }
    props.checked && addToStore();
};
const useEvent = (props, { isLimitExceeded }) => {
    const { elFormItem } = useCheckboxGroup();
    const { emit } = vue.getCurrentInstance();
    function handleChange(e) {
        var _a, _b;
        if (isLimitExceeded.value)
            return;
        const target = e.target;
        const value = target.checked
            ? (_a = props.trueLabel) !== null && _a !== void 0 ? _a : true : (_b = props.falseLabel) !== null && _b !== void 0 ? _b : false;
        emit('change', value, e);
    }
    vue.watch(() => props.modelValue, val => {
        var _a;
        (_a = elFormItem.formItemMitt) === null || _a === void 0 ? void 0 : _a.emit('el.form.change', [val]);
    });
    return {
        handleChange,
    };
};
const useCheckbox = (props) => {
    const { model, isLimitExceeded } = useModel(props);
    const { focus, size, isChecked, checkboxSize } = useCheckboxStatus(props, { model });
    const { isDisabled } = useDisabled(props, { model, isChecked });
    const { handleChange } = useEvent(props, { isLimitExceeded });
    setStoreValue(props, { model });
    return {
        isChecked,
        isDisabled,
        checkboxSize,
        model,
        handleChange,
        focus,
        size,
    };
};

var script = vue.defineComponent({
    name: 'ElCheckbox',
    props: {
        modelValue: {
            type: [Boolean, Number, String],
            default: () => undefined,
        },
        label: {
            type: [Boolean, Number, String],
        },
        indeterminate: Boolean,
        disabled: Boolean,
        checked: Boolean,
        name: {
            type: String,
            default: undefined,
        },
        trueLabel: {
            type: [String, Number],
            default: undefined,
        },
        falseLabel: {
            type: [String, Number],
            default: undefined,
        },
        id: {
            type: String,
            default: undefined,
        },
        controls: {
            type: String,
            default: undefined,
        },
        border: Boolean,
        size: {
            type: String,
            validator: validators.isValidComponentSize,
        },
    },
    emits: [constants.UPDATE_MODEL_EVENT, 'change'],
    setup(props) {
        return useCheckbox(props);
    },
});

const _hoisted_1 = /*#__PURE__*/vue.createVNode("span", { class: "el-checkbox__inner" }, null, -1 /* HOISTED */);
const _hoisted_2 = {
  key: 0,
  class: "el-checkbox__label"
};

function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (vue.openBlock(), vue.createBlock("label", {
    id: _ctx.id,
    class: ["el-checkbox", [
      _ctx.border && _ctx.checkboxSize ? 'el-checkbox--' + _ctx.checkboxSize : '',
      { 'is-disabled': _ctx.isDisabled },
      { 'is-bordered': _ctx.border },
      { 'is-checked': _ctx.isChecked }
    ]],
    "aria-controls": _ctx.indeterminate ? _ctx.controls : null
  }, [
    vue.createVNode("span", {
      class: ["el-checkbox__input", {
        'is-disabled': _ctx.isDisabled,
        'is-checked': _ctx.isChecked,
        'is-indeterminate': _ctx.indeterminate,
        'is-focus': _ctx.focus
      }],
      tabindex: _ctx.indeterminate ? 0 : false,
      role: _ctx.indeterminate ? 'checkbox' : false,
      "aria-checked": _ctx.indeterminate ? 'mixed' : false
    }, [
      _hoisted_1,
      (_ctx.trueLabel || _ctx.falseLabel)
        ? vue.withDirectives((vue.openBlock(), vue.createBlock("input", {
            key: 0,
            "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => (_ctx.model = $event)),
            checked: _ctx.isChecked,
            class: "el-checkbox__original",
            type: "checkbox",
            "aria-hidden": _ctx.indeterminate ? 'true' : 'false',
            name: _ctx.name,
            disabled: _ctx.isDisabled,
            "true-value": _ctx.trueLabel,
            "false-value": _ctx.falseLabel,
            onChange: _cache[2] || (_cache[2] = (...args) => (_ctx.handleChange && _ctx.handleChange(...args))),
            onFocus: _cache[3] || (_cache[3] = $event => (_ctx.focus = true)),
            onBlur: _cache[4] || (_cache[4] = $event => (_ctx.focus = false))
          }, null, 40 /* PROPS, HYDRATE_EVENTS */, ["checked", "aria-hidden", "name", "disabled", "true-value", "false-value"])), [
            [vue.vModelCheckbox, _ctx.model]
          ])
        : vue.withDirectives((vue.openBlock(), vue.createBlock("input", {
            key: 1,
            "onUpdate:modelValue": _cache[5] || (_cache[5] = $event => (_ctx.model = $event)),
            class: "el-checkbox__original",
            type: "checkbox",
            "aria-hidden": _ctx.indeterminate ? 'true' : 'false',
            disabled: _ctx.isDisabled,
            value: _ctx.label,
            name: _ctx.name,
            onChange: _cache[6] || (_cache[6] = (...args) => (_ctx.handleChange && _ctx.handleChange(...args))),
            onFocus: _cache[7] || (_cache[7] = $event => (_ctx.focus = true)),
            onBlur: _cache[8] || (_cache[8] = $event => (_ctx.focus = false))
          }, null, 40 /* PROPS, HYDRATE_EVENTS */, ["aria-hidden", "disabled", "value", "name"])), [
            [vue.vModelCheckbox, _ctx.model]
          ])
    ], 10 /* CLASS, PROPS */, ["tabindex", "role", "aria-checked"]),
    (_ctx.$slots.default || _ctx.label)
      ? (vue.openBlock(), vue.createBlock("span", _hoisted_2, [
          vue.renderSlot(_ctx.$slots, "default"),
          (!_ctx.$slots.default)
            ? (vue.openBlock(), vue.createBlock(vue.Fragment, { key: 0 }, [
                vue.createTextVNode(vue.toDisplayString(_ctx.label), 1 /* TEXT */)
              ], 64 /* STABLE_FRAGMENT */))
            : vue.createCommentVNode("v-if", true)
        ]))
      : vue.createCommentVNode("v-if", true)
  ], 10 /* CLASS, PROPS */, ["id", "aria-controls"]))
}

script.render = render;
script.__file = "packages/checkbox/src/checkbox.vue";

script.install = (app) => {
    app.component(script.name, script);
};
const _Checkbox = script;

exports.default = _Checkbox;
